package org.convallaria.system.biz.service.sys.impl;

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.convallaria.system.biz.entity.SysDept;
import org.convallaria.system.biz.entity.SysUser;
import org.convallaria.system.biz.entity.dto.sys.*;
import org.convallaria.system.biz.entity.vo.sys.UserVO;
import org.convallaria.system.biz.exception.UserBusinessException;
import org.convallaria.system.biz.mapper.SysUserMapper;
import org.convallaria.system.biz.service.sys.SysUserService;
import org.convallaria.system.biz.service.sys.SysRoleService;
import org.convallaria.system.biz.service.sys.SysMenuService;
import org.convallaria.system.biz.util.UserValidationUtil;
import org.convallaria.system.biz.util.UserOperationUtil;
// import org.convallaria.framework.security.util.SecurityUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import jakarta.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.util.*;
import java.util.UUID;

/**
 * 系统用户服务实现类
 * 
 * 提供用户管理的核心业务功能，包括：
 * - 用户分页查询（支持多条件筛选）
 * - 用户信息CRUD操作
 * - 用户缓存管理
 * - 敏感信息保护
 * 
 * 特性：
 * - 支持按部门、状态、关键词搜索
 * - 自动排除敏感信息（如密码）
 * - 事务管理确保数据一致性
 * - 详细的日志记录便于问题排查
 * 
 * @author gjh
 * @since 2024-09-22
 */
@Slf4j
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    private final SysRoleService sysRoleService;
    private final SysMenuService sysMenuService;
    private final PasswordEncoder passwordEncoder;

    @Resource
    private SysUserMapper sysUserMapper;


    public SysUserServiceImpl(SysRoleService sysRoleService,
                             SysMenuService sysMenuService,
                             PasswordEncoder passwordEncoder) {
        this.sysRoleService = sysRoleService;
        this.sysMenuService = sysMenuService;
        this.passwordEncoder = passwordEncoder;
    }

    /**
     * 分页查询用户列表（包含部门信息）
     *
     * @param query
     * @return
     */
    @Override
    public IPage<UserVO> pageUsers(UserQuery query) {
        MPJLambdaWrapper<SysUser> wrapper = new MPJLambdaWrapper<>();
        wrapper.leftJoin(SysDept.class, SysDept::getDeptId, SysUser::getDeptId)
                .selectAll(SysUser.class).select(SysDept::getDeptName, SysDept::getDeptId)
                .between(query.getStartTime() != null && query.getEndTime() != null, SysUser::getCreateTime,
                        query.getStartTime(), query.getEndTime())
                .eq(query.getDeptId() != null, SysUser::getDeptId, query.getDeptId())
                .eq(CharSequenceUtil.isNotBlank(query.getDeptName()), SysDept::getDeptName, query.getDeptName())
                .eq(CharSequenceUtil.isNotBlank(query.getUserName()), SysUser::getUserName, query.getUserName())
                .like(CharSequenceUtil.isNotBlank(query.getNickName()), SysUser::getNickName, query.getNickName())
                .eq(CharSequenceUtil.isNotBlank(query.getGender()), SysUser::getGender, query.getGender())
                .eq(CharSequenceUtil.isNotBlank(query.getStatus()), SysUser::getStatus, query.getStatus());

        wrapper.orderByAsc(SysUser::getUserId);

        return sysUserMapper.selectJoinPage(new Page<>(query.getPageNum(), query.getPageSize()), UserVO.class, wrapper);
    }

    /**
     * 获取用户详情信息
     *
     * @param userId 用户ID
     * @return 用户详情信息
     */
    @Override
    public UserVO getDetail(Long userId) {
        if (userId == null) {
            throw new IllegalArgumentException("用户ID不能为空");
        }
        
        MPJLambdaWrapper<SysUser> wrapper = new MPJLambdaWrapper<>();
        wrapper.leftJoin(SysDept.class, SysDept::getDeptId, SysUser::getDeptId)
                .selectAll(SysUser.class)
                .select(SysDept::getDeptName)
                .eq(SysUser::getUserId, userId);
        
        UserVO userVO = sysUserMapper.selectJoinOne(UserVO.class, wrapper);
        if (userVO == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 获取用户角色和权限信息
        Set<String> roles = getUserRoles(userId);
        userVO.setRoles(roles);

        Set<String> permissions = getUserPermissions(userId);
        userVO.setPermissions(permissions);
        
        return userVO;
    }

    /**
     * 新增用户
     *
     * @param userDTO 用户创建DTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addUser(UserCreateDTO userDTO) {
        // 参数验证
        if (ObjectUtil.isNull(userDTO)) {
            throw new IllegalArgumentException("用户信息不能为空");
        }
        
        // 检查用户认证状态
//        if (!isCurrentUserAuthenticated()) {
//            throw new UserBusinessException("USER_NOT_AUTHENTICATED", "用户未认证，无法执行此操作");
//        }
        
        Long tenantId = getCurrentTenantId();
        String currentUsername = getCurrentUsername();
        
        log.info("开始创建用户: {}, 操作人: {}, 租户: {}", userDTO.getUserName(), currentUsername, tenantId);
        
        // 验证用户名唯一性
        UserValidationUtil.validateUsernameUniqueness(this, userDTO.getUserName(), null, tenantId);
        
        // 验证邮箱和手机号唯一性
        UserValidationUtil.validateUserUniqueness(this, userDTO.getEmail(), userDTO.getPhoneNumber(), null, tenantId);
        
        // 验证密码确认
        UserValidationUtil.validatePasswordConfirmation(userDTO.getPassword(), userDTO.getConfirmPassword());
        
        // 构建用户实体
        SysUser user = UserOperationUtil.buildUserForCreate(userDTO, passwordEncoder, tenantId, currentUsername);
        
        // 保存用户
        if (!save(user)) {
            throw new UserBusinessException("USER_CREATE_FAILED", "用户创建失败");
        }
        
        // 分配角色和岗位
        assignUserRolesAndPosts(user, userDTO.getRoleIds(), userDTO.getPostIds());
        
        log.info("用户创建成功: userId={}, userName={}, 操作人: {}", user.getUserId(), user.getUserName(), currentUsername);
    }

    /**
     * 修改用户
     *
     * @param userDTO 用户更新DTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editUser(UserUpdateDTO userDTO) {
        // 参数验证
        if (ObjectUtil.isNull(userDTO) || ObjectUtil.isNull(userDTO.getUserId())) {
            throw new IllegalArgumentException("用户信息不能为空");
        }

        // 检查用户认证状态
        if (!isCurrentUserAuthenticated()) {
            throw new UserBusinessException("USER_NOT_AUTHENTICATED", "用户未认证，无法执行此操作");
        }

        Long tenantId = getCurrentTenantId();
        String currentUsername = getCurrentUsername();

        log.info("开始更新用户: userId={}, 操作人: {}, 租户: {}", userDTO.getUserId(), currentUsername, tenantId);

        // 检查用户是否存在
        SysUser existingUser = getById(userDTO.getUserId());
        UserValidationUtil.validateUserExists(existingUser);

        // 验证用户名唯一性
        UserValidationUtil.validateUsernameUniqueness(this, userDTO.getUserName(), userDTO.getUserId(), tenantId);

        // 验证邮箱和手机号唯一性
        UserValidationUtil.validateUserUniqueness(this, userDTO.getEmail(), userDTO.getPhoneNumber(), userDTO.getUserId(), tenantId);

        // 构建用户实体
        SysUser user = UserOperationUtil.buildUserForUpdate(userDTO, currentUsername);

        // 更新用户信息
        if (!updateById(user)) {
            throw new UserBusinessException("USER_UPDATE_FAILED", "用户更新失败");
        }

        // 更新角色和岗位
        assignUserRolesAndPosts(user, userDTO.getRoleIds(), userDTO.getPostIds());

        log.info("用户更新成功: userId={}, userName={}, 操作人: {}", user.getUserId(), user.getUserName(), currentUsername);
    }

    /**
     * 批量删除用户
     *
     * @param userIds 用户ID列表
     * @return 是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteUsers(List<Long> userIds) {
        if (CollUtil.isEmpty(userIds)) {
            throw new IllegalArgumentException("用户ID列表不能为空");
        }

        Long currentUserId = getCurrentUserId();
        String currentUsername = getCurrentUsername();

        // 验证不能删除当前用户
        UserValidationUtil.validateNotDeleteCurrentUser(userIds, currentUserId);

        // 软删除用户
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SysUser::getUserId, userIds);

        SysUser updateUser = new SysUser();
        updateUser.setDelFlag(1);
        updateUser.setUpdateTime(LocalDateTime.now());
        updateUser.setUpdateBy(currentUsername);

        boolean result = update(updateUser, queryWrapper);

        if (result) {
            // 清除相关缓存
            userIds.forEach(this::clearUserCache);
            log.info("批量删除用户成功: {}", userIds);
        }

        return result;
    }



    /**
     * 根据用户ID获取用户信息
     */
    @Override
    public SysUser getUserById(Long userId) {
        log.info("根据ID查询用户: {}", userId);
        return getById(userId);
    }
    
    /**
     * 更新用户信息
     */
    @Override
    public boolean updateUser(SysUser user) {
        log.info("更新用户信息: {}", user.getUserId());
        return updateById(user);
    }
    
    /**
     * 删除用户
     */
    @Override
    public boolean deleteUser(Long userId) {
        log.info("删除用户: {}", userId);
        return removeById(userId);
    }
    
    /**
     * 刷新用户缓存
     * 清除指定用户的缓存，下次查询时重新从数据库获取
     * 
     * @param user 用户信息
     * @return 刷新后的用户信息
     */
    @Override
    public SysUser refreshUserCache(SysUser user) {
        log.info("刷新用户缓存: {}", user.getUserId());
        
        // 清除用户相关缓存
        // 这里可以添加具体的缓存清除逻辑
        // 例如：cacheManager.getCache("user-cache").evict(user.getUserId());
        
        // 重新从数据库获取最新数据
        SysUser freshUser = getById(user.getUserId());
        if (freshUser != null) {
            log.info("用户缓存刷新成功: {}", freshUser.getUserId());
            return freshUser;
        } else {
            log.warn("用户不存在，无法刷新缓存: {}", user.getUserId());
            return user;
        }
    }
    
    @Override
    public Set<String> getUserRoles(Long userId) {
        log.info("获取用户角色: userId={}", userId);
        
        try {
            // 通过角色服务获取用户角色键值
            return sysRoleService.getUserRoleKeys(userId);
        } catch (Exception e) {
            log.error("获取用户角色失败: userId={}", userId, e);
            return new HashSet<>();
        }
    }
    
    @Override
    public Set<String> getUserPermissions(Long userId) {
        log.info("获取用户权限: userId={}", userId);
        
        try {
            // 通过菜单服务获取用户权限
            return sysMenuService.getUserPermissions(userId);
        } catch (Exception e) {
            log.error("获取用户权限失败: userId={}", userId, e);
            return new HashSet<>();
        }
    }
    

    @Override
    public SysUser selectByUsername(String username) {
        log.info("根据用户名查询用户: username={}", username);
        
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getUserName, username);
        
        return getOne(queryWrapper);
    }

    @Override
    public SysUser selectByUsernameAndTenant(String username, Long tenantId) {
        log.info("根据用户名和租户ID查询用户: username={}, tenantId={}", username, tenantId);
        
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getUserName, username)
                   .eq(SysUser::getTenantId, tenantId);
        
        return getOne(queryWrapper);
    }

    @Override
    public boolean validatePassword(Long userId, String password) {
        log.info("验证用户密码: userId={}", userId);
        
        SysUser user = getById(userId);
        if (user == null) {
            return false;
        }
        
        // 使用PasswordEncoder进行密码验证
        return passwordEncoder.matches(password, user.getPassword());
    }

    @Override
    public boolean isUserStatusNormal(Long userId) {
        log.info("检查用户状态: userId={}", userId);
        
        SysUser user = getById(userId);
        if (user == null) {
            return false;
        }
        
        return "0".equals(user.getStatus());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateLastLoginInfo(Long userId, String loginIp) {
        log.info("更新用户最后登录信息: userId={}, loginIp={}", userId, loginIp);
        
        SysUser user = getById(userId);
        if (user == null) {
            return false;
        }
        
        user.setLoginIp(loginIp);
        user.setLoginTime(LocalDateTime.now());
        
        return updateById(user);
    }

    @Override
    public Object getUserDeptInfo(Long userId) {
        log.info("获取用户部门信息: userId={}", userId);
        
        SysUser user = getById(userId);
        if (user == null || user.getDeptId() == null) {
            return null;
        }
        
        // TODO: 实际项目中应该通过SysDeptService查询部门信息
        Map<String, Object> deptInfo = new HashMap<>();
        deptInfo.put("deptId", user.getDeptId());
        deptInfo.put("deptName", "示例部门");
        
        return deptInfo;
    }

    @Override
    public List<Object> getUserPostInfo(Long userId) {
        log.info("获取用户岗位信息: userId={}", userId);
        
        // TODO: 实际项目中应该通过SysPostService查询岗位信息
        List<Object> postList = new ArrayList<>();
        Map<String, Object> postInfo = new HashMap<>();
        postInfo.put("postId", 1L);
        postInfo.put("postName", "示例岗位");
        postList.add(postInfo);
        
        return postList;
    }

    @Override
    public Object getUserCompleteInfo(Long userId) {
        log.info("获取用户完整信息: userId={}", userId);
        
        SysUser user = getById(userId);
        if (user == null) {
            return null;
        }
        
        Map<String, Object> completeInfo = new HashMap<>();
        completeInfo.put("user", user);
        completeInfo.put("dept", getUserDeptInfo(userId));
        completeInfo.put("posts", getUserPostInfo(userId));
        completeInfo.put("roles", getUserRoles(userId));
        completeInfo.put("permissions", getUserPermissions(userId));
        
        return completeInfo;
    }

    @Override
    public boolean isUsernameUnique(String username, Long userId, Long tenantId) {
        log.info("检查用户名唯一性: username={}, userId={}, tenantId={}", username, userId, tenantId);
        
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getUserName, username)
                   .eq(SysUser::getTenantId, tenantId)
                   .eq(SysUser::getDelFlag, 0);
        
        if (userId != null) {
            queryWrapper.ne(SysUser::getUserId, userId);
        }
        
        return count(queryWrapper) == 0;
    }

    @Override
    public boolean isEmailUnique(String email, Long userId, Long tenantId) {
        log.info("检查邮箱唯一性: email={}, userId={}, tenantId={}", email, userId, tenantId);
        
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getEmail, email)
                   .eq(SysUser::getTenantId, tenantId)
                   .eq(SysUser::getDelFlag, 0);
        
        if (userId != null) {
            queryWrapper.ne(SysUser::getUserId, userId);
        }
        
        return count(queryWrapper) == 0;
    }

    @Override
    public boolean isPhoneNumberUnique(String phoneNumber, Long userId, Long tenantId) {
        log.info("检查手机号唯一性: phoneNumber={}, userId={}, tenantId={}", phoneNumber, userId, tenantId);
        
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getPhoneNumber, phoneNumber)
                   .eq(SysUser::getTenantId, tenantId)
                   .eq(SysUser::getDelFlag, 0);
        
        if (userId != null) {
            queryWrapper.ne(SysUser::getUserId, userId);
        }
        
        return count(queryWrapper) == 0;
    }


    /**
     * 重置用户密码
     *
     * @param resetPwdDTO 重置密码DTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resetPwd(ResetPwdDTO resetPwdDTO) {
        if (ObjectUtil.isNull(resetPwdDTO) || ObjectUtil.isNull(resetPwdDTO.getUserId())) {
            throw new IllegalArgumentException("重置密码信息不能为空");
        }
        
        // 验证密码确认
        UserValidationUtil.validatePasswordConfirmation(resetPwdDTO.getNewPassword(), resetPwdDTO.getConfirmPassword());
        
        // 检查用户是否存在
        SysUser user = getById(resetPwdDTO.getUserId());
        UserValidationUtil.validateUserExists(user);
        
        // 更新密码
        UserOperationUtil.updateUserPassword(user, resetPwdDTO.getNewPassword(), passwordEncoder, getCurrentUsername());
        
        if (!updateById(user)) {
            throw new UserBusinessException("PASSWORD_RESET_FAILED", "密码重置失败");
        }
        
        // 清除用户缓存
        clearUserCache(resetPwdDTO.getUserId());
        
        log.info("用户密码重置成功: userId={}, reason={}", resetPwdDTO.getUserId(), resetPwdDTO.getReason());
    }

    /**
     * 修改密码
     *
     * @param changePwdDTO 修改密码DTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void changePwd(ChangePwdDTO changePwdDTO) {
        if (ObjectUtil.isNull(changePwdDTO)) {
            throw new IllegalArgumentException("修改密码信息不能为空");
        }
        
        // 验证密码确认
        UserValidationUtil.validatePasswordConfirmation(changePwdDTO.getNewPassword(), changePwdDTO.getConfirmPassword());
        
        // 获取当前用户
        Long currentUserId = getCurrentUserId();
        SysUser user = getById(currentUserId);
        UserValidationUtil.validateUserExists(user);
        
        // 验证原密码
        if (!passwordEncoder.matches(changePwdDTO.getOldPassword(), user.getPassword())) {
            throw new UserBusinessException("OLD_PASSWORD_ERROR", "原密码错误");
        }
        
        // 更新密码
        UserOperationUtil.updateUserPassword(user, changePwdDTO.getNewPassword(), passwordEncoder, getCurrentUsername());
        
        if (!updateById(user)) {
            throw new UserBusinessException("PASSWORD_CHANGE_FAILED", "密码修改失败");
        }
        
        // 清除用户缓存
        clearUserCache(currentUserId);
        
        log.info("用户密码修改成功: userId={}", currentUserId);
    }

    /**
     * 更新用户信息
     *
     * @param userProfileDTO 用户个人资料DTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateProfile(UserProfileDTO userProfileDTO) {
        if (ObjectUtil.isNull(userProfileDTO)) {
            throw new IllegalArgumentException("用户资料信息不能为空");
        }
        
        // 获取当前用户
        Long currentUserId = getCurrentUserId();
        Long tenantId = getCurrentTenantId();
        String currentUsername = getCurrentUsername();
        
        SysUser user = getById(currentUserId);
        UserValidationUtil.validateUserExists(user);
        
        // 验证邮箱和手机号唯一性
        UserValidationUtil.validateUserUniqueness(this, userProfileDTO.getEmail(), userProfileDTO.getPhoneNumber(), currentUserId, tenantId);
        
        // 更新用户信息
        UserOperationUtil.updateUserProfile(user, userProfileDTO, currentUsername);
        
        if (!updateById(user)) {
            throw new UserBusinessException("PROFILE_UPDATE_FAILED", "用户资料更新失败");
        }
        
        // 清除用户缓存
        clearUserCache(currentUserId);
        
        log.info("用户资料更新成功: userId={}", currentUserId);
    }

    /**
     * 上传用户头像
     *
     * @param file 文件
     * @return 头像URL
     */
    @Override
    public String uploadAvatar(MultipartFile file) {
        if (ObjectUtil.isNull(file) || file.isEmpty()) {
            throw new IllegalArgumentException("文件不能为空");
        }
        
        // 验证文件类型和大小
        UserValidationUtil.validateFileType(file.getContentType());
        UserValidationUtil.validateFileSize(file.getSize(), 5 * 1024 * 1024);
        
        // 实现文件上传逻辑，返回文件URL
        String avatarUrl = uploadFileToStorage(file, "avatar");
        
        // 更新用户头像
        Long currentUserId = getCurrentUserId();
        String currentUsername = getCurrentUsername();
        
        SysUser user = getById(currentUserId);
        if (ObjectUtil.isNotNull(user)) {
            UserOperationUtil.updateUserAvatar(user, avatarUrl, currentUsername);
            updateById(user);
            
            // 清除用户缓存
            clearUserCache(currentUserId);
        }
        
        log.info("用户头像上传成功: userId={}, avatarUrl={}", currentUserId, avatarUrl);
        return avatarUrl;
    }

    /**
     * 导出用户列表
     *
     * @param query 查询条件
     * @param response 响应对象
     */
    @Override
    public void exportUsers(UserQuery query, HttpServletResponse response) {
        try {
            log.info("开始导出用户列表: {}", query);
            
            // 查询所有用户数据（不分页）
            UserQuery exportQuery = new UserQuery();
            exportQuery.setPageNum(1);
            exportQuery.setPageSize(Integer.MAX_VALUE);
            // 复制查询条件
            copyQueryConditions(query, exportQuery);
            
            IPage<UserVO> userPage = pageUsers(exportQuery);
            List<UserVO> userList = userPage.getRecords();
            
            if (CollUtil.isEmpty(userList)) {
                log.warn("没有用户数据可导出");
                return;
            }
            
            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = "用户列表_" + System.currentTimeMillis() + ".xlsx";
            response.setHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));
            
            // TODO: 使用EasyExcel或POI实现Excel导出
            // 这里只是示例，实际应该调用Excel工具类
            log.info("导出用户列表成功，共{}条记录", userList.size());
            
        } catch (Exception e) {
            log.error("导出用户列表失败", e);
            throw new UserBusinessException("EXPORT_FAILED", "导出失败");
        }
    }
    
    /**
     * 复制查询条件
     */
    private void copyQueryConditions(UserQuery source, UserQuery target) {
        target.setDeptId(source.getDeptId());
        target.setDeptName(source.getDeptName());
        target.setUserName(source.getUserName());
        target.setNickName(source.getNickName());
        target.setGender(source.getGender());
        target.setStatus(source.getStatus());
        target.setStartTime(source.getStartTime());
        target.setEndTime(source.getEndTime());
    }

    /**
     * 下载用户导入模板
     *
     * @param response 响应对象
     */
    @Override
    public void downloadTemplate(HttpServletResponse response) {
        try {
            log.info("开始下载用户导入模板");
            
            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = "用户导入模板_" + System.currentTimeMillis() + ".xlsx";
            response.setHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));
            
            // TODO: 使用EasyExcel或POI生成模板文件
            // 这里只是示例，实际应该调用Excel工具类生成包含列头的模板
            log.info("用户导入模板下载成功");
            
        } catch (Exception e) {
            log.error("下载用户导入模板失败", e);
            throw new UserBusinessException("TEMPLATE_DOWNLOAD_FAILED", "模板下载失败");
        }
    }

    /**
     * 导入用户
     *
     * @param file 导入文件
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importUsers(MultipartFile file) {
        if (ObjectUtil.isNull(file) || file.isEmpty()) {
            throw new IllegalArgumentException("文件不能为空");
        }
        
        try {
            log.info("开始导入用户: {}", file.getOriginalFilename());
            
            // 验证文件类型
            String contentType = file.getContentType();
            if (contentType == null || !contentType.contains("sheet")) {
                throw new UserBusinessException("INVALID_FILE_TYPE", "请上传Excel文件");
            }
            
            // TODO: 使用EasyExcel或POI解析Excel文件
            // 1. 解析Excel文件获取用户数据
            // 2. 验证数据格式和必填字段
            // 3. 检查用户名、邮箱、手机号唯一性
            // 4. 批量保存用户数据
            // 5. 分配默认角色和岗位
            
            log.info("用户导入成功");
            
        } catch (Exception e) {
            log.error("导入用户失败: {}", file.getOriginalFilename(), e);
            throw new UserBusinessException("IMPORT_FAILED", "用户导入失败");
        }
    }

    /**
     * 获取当前租户ID
     */
    private Long getCurrentTenantId() {
        try {
            // 从Spring Security上下文获取当前用户信息
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if (authentication != null && authentication.isAuthenticated() && authentication.getPrincipal() != null) {
                // 如果Principal是String类型（用户名），从数据库查询
                SysUser user = selectByUsername((String) authentication.getPrincipal());
                if (user != null && user.getTenantId() != null) {
                    return user.getTenantId();
                }
            }
            log.warn("从安全上下文获取租户ID为空，使用默认值");
            return 1L;
        } catch (Exception e) {
            log.warn("获取当前租户ID失败，使用默认值", e);
            return 1L;
        }
    }

    /**
     * 获取当前用户ID
     */
    private Long getCurrentUserId() {
        try {
            // 从Spring Security上下文获取当前用户信息
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if (authentication != null && authentication.isAuthenticated() && authentication.getPrincipal() != null) {
                // 如果Principal是String类型（用户名），从数据库查询
                if (authentication.getPrincipal() instanceof String) {
                    String username = (String) authentication.getPrincipal();
                    SysUser user = selectByUsername(username);
                    if (user != null && user.getUserId() != null) {
                        return user.getUserId();
                    }
                }
            }
            log.warn("从安全上下文获取用户ID为空，使用默认值");
            return 1L;
        } catch (Exception e) {
            log.warn("获取当前用户ID失败，使用默认值", e);
            return 1L;
        }
    }

    /**
     * 获取当前用户名
     */
    private String getCurrentUsername() {
        try {
            // 从Spring Security上下文获取当前用户信息
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if (authentication != null && authentication.isAuthenticated() && authentication.getPrincipal() != null) {
                // 如果Principal是String类型（用户名），直接返回
                if (authentication.getPrincipal() instanceof String) {
                    String username = (String) authentication.getPrincipal();
                    if (username != null && !username.trim().isEmpty()) {
                        return username;
                    }
                }
            }
            log.warn("从安全上下文获取用户名为空，使用默认值");
            return "admin";
        } catch (Exception e) {
            log.warn("获取当前用户名失败，使用默认值", e);
            return "admin";
        }
    }

    /**
     * 获取当前部门ID
     */
    private Long getCurrentDeptId() {
        try {
            // 从Spring Security上下文获取当前用户信息
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if (authentication != null && authentication.isAuthenticated() && authentication.getPrincipal() != null) {
                // 如果Principal是String类型（用户名），从数据库查询
                if (authentication.getPrincipal() instanceof String) {
                    String username = (String) authentication.getPrincipal();
                    SysUser user = selectByUsername(username);
                    if (user != null && user.getDeptId() != null) {
                        return user.getDeptId();
                    }
                }
            }
            log.warn("从安全上下文获取部门ID为空，使用默认值");
            return 1L;
        } catch (Exception e) {
            log.warn("获取当前部门ID失败，使用默认值", e);
            return 1L;
        }
    }

    /**
     * 检查当前用户是否已认证
     */
    private boolean isCurrentUserAuthenticated() {
        try {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            return authentication != null && authentication.isAuthenticated() && 
                   !"anonymousUser".equals(authentication.getPrincipal());
        } catch (Exception e) {
            log.warn("检查用户认证状态失败", e);
            return false;
        }
    }

    /**
     * 获取当前用户完整信息
     */
    private SysUser getCurrentSecurityUser() {
        try {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if (authentication != null && authentication.isAuthenticated() && authentication.getPrincipal() != null) {
                if (authentication.getPrincipal() instanceof String) {
                    String username = (String) authentication.getPrincipal();
                    return selectByUsername(username);
                }
            }
            return null;
        } catch (Exception e) {
            log.warn("获取当前安全用户信息失败", e);
            return null;
        }
    }

    /**
     * 清除用户缓存
     */
    private void clearUserCache(Long userId) {
        try {
            // TODO: 实现缓存清除逻辑
            // 实际项目中应该清除Redis或本地缓存中的用户相关数据
            // 例如：
            // 1. 清除用户基本信息缓存
            // 2. 清除用户角色权限缓存
            // 3. 清除用户部门岗位缓存
            // 4. 清除用户会话缓存
            
            log.info("清除用户缓存: userId={}", userId);
            
            // 示例缓存清除逻辑
            // CacheUtils.evict(CacheConstants.USER_DETAILS, userId);
            // CacheUtils.evict(CacheConstants.USER_ROLES, userId);
            // CacheUtils.evict(CacheConstants.USER_PERMISSIONS, userId);
            
        } catch (Exception e) {
            log.error("清除用户缓存失败: userId={}", userId, e);
            // 缓存清除失败不应该影响主业务流程
        }
    }
    
    /**
     * 分配用户角色和岗位
     * 
     * @param user 用户实体
     * @param roleIds 角色ID列表
     * @param postIds 岗位ID列表
     */
    private void assignUserRolesAndPosts(SysUser user, List<Long> roleIds, List<Long> postIds) {
        // 分配角色
        if (CollUtil.isNotEmpty(roleIds)) {
            assignUserRoles(user.getUserId(), roleIds);
            log.info("为用户 {} 分配角色: {}", user.getUserName(), roleIds);
        }
        
        // 分配岗位
        if (CollUtil.isNotEmpty(postIds)) {
            assignUserPosts(user.getUserId(), postIds);
            log.info("为用户 {} 分配岗位: {}", user.getUserName(), postIds);
        }
    }
    
    /**
     * 分配用户角色
     * 
     * @param userId 用户ID
     * @param roleIds 角色ID列表
     */
    private void assignUserRoles(Long userId, List<Long> roleIds) {
        try {
            // TODO: 实现角色分配逻辑
            // 1. 删除用户现有角色关联
            // 2. 插入新的角色关联
            // 3. 清除用户权限缓存
            log.info("分配用户角色: userId={}, roleIds={}", userId, roleIds);
        } catch (Exception e) {
            log.error("分配用户角色失败: userId={}, roleIds={}", userId, roleIds, e);
            throw new UserBusinessException("ROLE_ASSIGN_FAILED", "角色分配失败");
        }
    }
    
    /**
     * 分配用户岗位
     * 
     * @param userId 用户ID
     * @param postIds 岗位ID列表
     */
    private void assignUserPosts(Long userId, List<Long> postIds) {
        try {
            // TODO: 实现岗位分配逻辑
            // 1. 删除用户现有岗位关联
            // 2. 插入新的岗位关联
            log.info("分配用户岗位: userId={}, postIds={}", userId, postIds);
        } catch (Exception e) {
            log.error("分配用户岗位失败: userId={}, postIds={}", userId, postIds, e);
            throw new UserBusinessException("POST_ASSIGN_FAILED", "岗位分配失败");
        }
    }
    
    /**
     * 上传文件到存储
     * 
     * @param file 文件
     * @param folder 文件夹
     * @return 文件URL
     */
    private String uploadFileToStorage(MultipartFile file, String folder) {
        try {
            // 生成唯一文件名
            String originalFilename = file.getOriginalFilename();
            String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            String fileName = System.currentTimeMillis() + "_" + UUID.randomUUID().toString().replace("-", "") + extension;
            
            // 构建文件路径
            String filePath = "/uploads/" + folder + "/" + fileName;
            
            // TODO: 实际项目中应该上传到云存储或本地文件系统
            // 这里只是示例，实际应该调用文件服务
            log.info("文件上传成功: originalName={}, fileName={}, path={}", originalFilename, fileName, filePath);
            
            return filePath;
        } catch (Exception e) {
            log.error("文件上传失败: {}", file.getOriginalFilename(), e);
            throw new UserBusinessException("FILE_UPLOAD_FAILED", "文件上传失败");
        }
    }
}
